package com.yxh.lib_base.base.viewmodel

import com.yxh.lib_base.ext.lazyNone
import com.yxh.lib_base.ext.livedata.event.EventLiveData
import com.yxh.lib_base.network.AppException


/**
 * @作者：yuan_xh
 * @时间：2022/9/12 10:08
 * @描述：
 **/
abstract class BaseListViewModule<T> : BaseViewModel() {
    private val _startPageNo = 1
    protected var _pageNo = _startPageNo
    protected var _PageSize: Int = 20

    protected val _datas = mutableListOf<T>()
    val loadList = EventLiveData<LoadSuccess<T>>()

    /**
     * 切换布局 - 默认显示布局
     * */
    val switchPage by lazyNone {
        EventLiveData<ListPageConfig>().apply { value = ListPageConfig.Show }
    }

    val loadingStart by lazyNone { EventLiveData<LoadingStart>() }


    /**只有刷新没加载更多*/
    abstract fun requestData(page: Int)

    fun refresh() {
        _pageNo = _startPageNo
        requestData(_pageNo)
    }

    fun loadMore() {
        _pageNo += 1
        requestData(_pageNo)
    }

    /**
     * 请求数据成功处理
     */
    protected fun handleItemData(page: Int, data: List<T>) {
        if (isRefresh(page)) {
            handleItemDataRefresh(data.toMutableList())
        } else {
            handleItemDataLoadMove(page, data.toMutableList())
        }
        if (_datas.isNotEmpty()) {
            switchToList()
        } else {
            switchToEmpty()
        }
    }

    private fun handleItemDataRefresh(data: MutableList<T>) {
        _datas.clear()
        _datas.addAll(data)
        loadList.value = LoadSuccess(true, data)
        //刷新完成
        loadingStart.value = LoadingStart.RefreshSuccess
    }

    private fun handleItemDataLoadMove(page: Int, data: MutableList<T>) {
        if (data.isNotEmpty()) {
            _datas.addAll(data)
            if (data.size < _PageSize) {
                //加载更多完成
                loadList.value = LoadSuccess(false, data)
                //没有更多数据
                loadingStart.value = LoadingStart.LoadMoreNoData
            } else {
                //加载更多完成
                loadList.value = LoadSuccess(false, data)
                loadingStart.value = LoadingStart.LoadMoreSuccess
            }
        } else {
            pageNoMinus()
            //加载更多完成
            loadList.value = LoadSuccess(false, data)
            //没有更多数据
            loadingStart.value = LoadingStart.LoadMoreNoData
        }
    }


    /**
     * 请求数据失败处理
     */
    protected fun handleError(page: Int, error: AppException) {
        if (isRefresh(page)) {
            loadingStart.value = LoadingStart.RefreshError
            switchToError()
            if (_datas.isEmpty()) {
                switchToEmpty()
            }
        } else {
            pageNoMinus()
            loadingStart.value = LoadingStart.LoadMoreError
            switchToError()
        }
    }

    private fun pageNoMinus() {
        _pageNo.minus(1)
    }

    /**
     * @param page
     * @return 判断是否是刷新 {如果page==_startPageNo 认为是刷新列表,否则认为是加载更多}
     * */
    fun isRefresh(page: Int): Boolean {
        return page == _startPageNo
    }

    /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     *                     todo 页面布局切换
     * ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~   */
    fun switchToList() {
        switchPage.postValue(ListPageConfig.Show)
    }

    fun switchToEmpty() {
        switchPage.postValue(ListPageConfig.Empty)
    }

    fun switchToLoading() {
        switchPage.postValue(ListPageConfig.Loading)
    }

    fun switchToError() {
        switchPage.postValue(ListPageConfig.Error)
    }
}


/**
 * 页面状态 - 用于切换页面
 * */
class ListPageConfig(type: Int, des: String) {
    companion object {
        val Show = ListPageConfig(1, "显示")
        val Loading = ListPageConfig(2, "Loading页")
        val Error = ListPageConfig(3, "失败页")
        val Empty = ListPageConfig(4, "缺省页")
    }
}

/**
 * 请求失败
 * */
class LoadingStart(type: Int) {
    companion object {
        val RefreshSuccess = LoadingStart(0)
        val RefreshError = LoadingStart(1)
        val LoadMoreSuccess = LoadingStart(2)
        val LoadMoreError = LoadingStart(3)
        val LoadMoreNoData = LoadingStart(4)
    }
}


/**
 * 请求成功
 * */
class LoadSuccess<T>(val isRefresh: Boolean, val list: MutableList<T>) {
    fun doRefresh(success: (data: MutableList<T>) -> Unit): LoadSuccess<T> {
        if (isRefresh) {
            success.invoke(list)
        }
        return this
    }

    fun doLoadMove(success: (data: MutableList<T>) -> Unit): LoadSuccess<T> {
        if (!isRefresh) {
            success.invoke(list)
        }
        return this
    }
}